package util

import (
	"fmt"
	"regexp"
	"strings"
	"unicode"

	"github.com/mozillazg/go-pinyin"
	"github.com/spf13/cast"
)

func PtrStr(str string) *string {
	return &str
}
func PtrInt(num int) *int {
	return &num
}

func ReplaceWrap(str string) string {
	return strings.ReplaceAll(str, "\n", "\\n")
}

func ReplaceWildcard(str string, rule map[string]string) string {
	reg, _ := regexp.Compile("{\\w+}")
	matchList := reg.FindAllString(str, -1)
	for _, match := range matchList {
		key := match[1 : len(match)-1]
		if value, ok := rule[key]; ok {
			str = strings.ReplaceAll(str, match, value)
		}
	}
	return str
}

var SizeUnits = []string{"B", "K", "M", "G"}

func ConvSize(sizeB int64) string {
	var size = float64(sizeB)
	count := 0
	for size > 1024 && count < len(SizeUnits)-1 {
		size /= 1024
		count++
	}
	return fmt.Sprintf("%.2f%s", size, SizeUnits[count])
}

func ParseSize(sizeStr string) (int64, error) {
	if len(sizeStr) == 0 {
		return 0, nil
	}
	sizeStr = strings.ToUpper(strings.TrimSpace(sizeStr))
	unit := sizeStr[len(sizeStr)-1:]
	index := InStrArray(unit, SizeUnits)
	if index < 0 {
		return 0, fmt.Errorf("unit err")
	}
	size := cast.ToFloat64(sizeStr[:len(sizeStr)-1])
	for i := 0; i < index; i++ {
		size *= 1024
	}
	return int64(size), nil
}

func hasCh(s string) bool {
	for _, ch := range s {
		if unicode.Is(unicode.Han, ch) {
			return true
		}
	}
	return false
}

func ch2Py(s string) string {
	if !hasCh(s) {
		return s
	}
	return strings.Join(pinyin.LazyConvert(s, nil), " ")
}

func bool2Int(b bool) int {
	if b {
		return 1
	}
	return -1
}

// 文本排序
func CmpText(str1, str2 string) int {
	if str1 == str2 {
		return 0
	}
	// 存在空字符串
	if len(str1) == 0 || len(str2) == 0 {
		return bool2Int(str1 < str2)
	}
	// 忽略大小写
	str1, str2 = strings.ToLower(str1), strings.ToLower(str2)

	s1, s2 := []rune(str1), []rune(str2)
	// 找到第一个不同字符
	firstDiff := 0
	for firstDiff < len(s1) && firstDiff < len(s2) && s1[firstDiff] == s2[firstDiff] {
		firstDiff++
	}

	// 截断关系
	if firstDiff >= len(s1) || firstDiff >= len(s2) {
		return bool2Int(str1 < str2)
	}

	// 比较第一个diff字符
	ch1, ch2 := s1[firstDiff], s2[firstDiff]

	// 两个字符都是中文时，转拼音比较
	if unicode.Is(unicode.Han, ch1) && unicode.Is(unicode.Han, ch2) {
		return bool2Int(ch2Py(string(ch1)) < ch2Py(string(ch2)))
	}

	return bool2Int(ch1 < ch2)
}
